from rest_framework import serializers
from app01.models import (User,
                          Article,
                          ArticleTag,
                          Tag,
                          Comment)
from rest_framework.validators import ValidationError
from django.contrib.auth import authenticate


class UserSerializer(serializers.ModelSerializer):
    created_at = serializers.DateTimeField(format='%Y-%m-%d %H:%M:%S', required=False, read_only=True)

    def validate_username(self, value):
        if User.objects.filter(username=value):
            raise ValidationError("username already exists.")
        return value

    def validate_email(self, value):
        if User.objects.filter(email=value):
            raise ValidationError("email already exists.")
        return value

    def validate_nickname(self, value):
        if not value:
            name = "未命名用户"
            return name
        return value

    def create(self, validated_data):
        user = User.objects.create(username=validated_data['username'],
                                   email=validated_data['email'],
                                   nickname=validated_data['nickname']
                                   )
        user.set_password(validated_data['password'])
        user.save()
        return user

    class Meta:
        model = User
        fields = ['user_id', 'username', 'password', 'email', 'nickname', 'created_at']
        extra_kwargs = {
            'user_id': {'read_only': True},
            'password': {'write_only': True},
            'created_at': {'read_only': True},
        }


class LoginSerializer(serializers.ModelSerializer):
    username = serializers.CharField(max_length=32)
    password = serializers.CharField(write_only=True, max_length=255)

    def validate(self, attrs):
        username = attrs.get('username')
        password = attrs.get('password')

        use = User.objects.filter(username=username, password=password).first()
        user = authenticate(request=self.context.get('request'), username=username, password=password)

        if user is None:
            raise serializers.ValidationError("用户名或密码错误")

        if not user.check_password(password):
            raise serializers.ValidationError("用户名或密码错误")

        attrs['user'] = user
        return attrs

    class Meta:
        model = User
        fields = ['username', 'password']


class ArticleSerializer(serializers.ModelSerializer):
    tag_ids = serializers.ListField(child=serializers.IntegerField(), write_only=True)

    def validate_author_id(self, value):
        if not User.objects.filter(user_id=value):
            raise ValidationError("author_id does not exist.")
        return value

    def validate_tag_ids(self, value):
        if not Tag.objects.filter(tag_id__in=value).count() == len(value):
            raise serializers.ValidationError("One or more tag_ids are invalid.")
        return value

    def create(self, validated_data):
        tag_ids = validated_data.pop('tag_ids', [])
        article = Article.objects.create(**validated_data)
        for tag_id in tag_ids:
            ArticleTag.objects.create(article_id=article.article_id, tag_id=tag_id)
        return article

    class Meta:
        model = Article
        fields = '__all__'


class ArticleTagSerializer(serializers.ModelSerializer):

    def validate_tag_id(self, value):
        if not Tag.objects.filter(tag_id=value):
            raise ValidationError("tag_id does not exist")
        return value

    def validate_article_id(self, value):
        if not Article.objects.filter(article_id=value):
            raise ValidationError("article_id does not exist")
        return value

    class Meta:
        model = ArticleTag
        fields = '__all__'


class TagSerializer(serializers.ModelSerializer):
    class Meta:
        model = Tag
        fields = '__all__'


class CommentSerializer(serializers.ModelSerializer):
    created_at = serializers.DateTimeField(format='%Y-%m-%d %H:%M:%S', required=False, read_only=True)

    def validate_article_id(self, value):
        if not Article.objects.filter(article_id=value):
            raise ValidationError("article_id does not exist")
        return value

    def validate_author_id(self, value):
        if not User.objects.filter(user_id=value):
            raise ValidationError("author_id does not exist")
        return value

    def validate_parent_comment_id(self, value):
        if not Comment.objects.filter(comment_id=value):
            raise ValidationError("parent_comment_id does not exist")
        return value

    class Meta:
        model = Comment
        fields = '__all__'
